package com.mycompany.app.hr.security.service.ldap;

import java.util.List;

import javax.naming.NamingException;
import javax.naming.directory.Attributes;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;

import com.mycompany.app.hr.security.exception.UserPassowrdNotMatchInLDAPException;

public class UserLDAPAuthenService implements IUserLDAPAuthenService {

    private final static Log logger = LogFactory
            .getLog(UserLDAPAuthenService.class);

    private LdapTemplate ldapTemplate;

    public void setLdapTemplate(LdapTemplate ldapTemplate) {

        this.ldapTemplate = ldapTemplate;
    }

    // TODO
    public void addUserAuthen(String username, String lastName,
            String firstName, String middleName, String mail, String password)
            throws NamingException {

        // Name dn = buildDn(p);
        // DirContextAdapter context = new DirContextAdapter(dn);
        //
        // context.setAttributeValues("objectclass", new String[] {"top",
        // "person"});
        // context.setAttributeValue("cn", p.getFullname());
        // context.setAttributeValue("sn", p.getLastname());
        // context.setAttributeValue("description", p.getDescription());
        //
        // ldapTemplate.bind(dn, context, null);

    }

    public void changePassword(String username, String oldPassword,
            String newPassword) throws UserPassowrdNotMatchInLDAPException,
            NamingException {

        if (userAuthen(username, oldPassword)) {
            resetPassword(username, newPassword);
        } else {
            throw new UserPassowrdNotMatchInLDAPException(
                    "the username:"
                            + username
                            + " doesn't exist or username/passord doesn't match in ldap database!");
        }

    }

    public void deleteUserAuthen(String username) throws NamingException {

        String dn = buildDN(username);
        ldapTemplate.unbind(dn);
        logger.debug("unbind uid " + username);
    }

    public void resetPassword(String username, String newPassword)
            throws NamingException {

        String dn = buildDN(username);
        DirContextOperations context = (DirContextOperations) ldapTemplate
                .lookup(dn);
        context.setAttributeValue("userpassword", newPassword);
        ldapTemplate.modifyAttributes(context);

    }

    public void updateEmailAddress(String username, String emailAddr)
            throws NamingException {

        String dn = buildDN(username);
        DirContextOperations context = (DirContextOperations) ldapTemplate
                .lookup(dn);
        context.setAttributeValue("mail", emailAddr);
        ldapTemplate.modifyAttributes(context);

    }

    public void updateNameInfo(String username, String lastName,
            String firstName, String middleName) throws NamingException {

        throw new UnsupportedOperationException();

    }

    @SuppressWarnings("unchecked")
    public boolean userAuthen(String username, String password)
            throws NamingException {

        AndFilter filter = new AndFilter();
        filter.and(new EqualsFilter("uid", username));
        filter.and(new EqualsFilter("userPassword", password));
        List l = ldapTemplate.search(getMyEntryBase(username), filter.encode(),
                new AttributesMapper() {
                    public Object mapFromAttributes(Attributes attrs)
                            throws NamingException {

                        return attrs;
                    }
                });
        if (l.size() > 0) {
            logger.debug(username + " match in ldap server");
            return true;
        } else {
            logger.debug(username + " don't match in ldap server");
            return false;
        }

    }

    /**
     * build DN based from rdn(usually uid)
     * 
     * @param rdn
     * @return
     */
    private String buildDN(String rdn) {

        StringBuilder sb = new StringBuilder("uid=");
        sb.append(rdn).append(",").append(getMyEntryBase(rdn));
        logger.debug("build ND  " + sb.toString());
        return sb.toString();
    }

    private String getMyEntryBase(String userName) {

        final String ouPeople = "ou=People,o=bearingpoint,c=com";
        final String ouPeople0 = "ou=People0,o=bearingpoint,c=com";
        final String ouPeople1 = "ou=People1,o=bearingpoint,c=com";
        final String ouPeople2 = "ou=People2,o=bearingpoint,c=com";
        final String ouPeople3 = "ou=People3,o=bearingpoint,c=com";
        final String ouPeople4 = "ou=People4,o=bearingpoint,c=com";
        final String ouPeople5 = "ou=People5,o=bearingpoint,c=com";
        final String ouPeople6 = "ou=People6,o=bearingpoint,c=com";
        final String ouPeople7 = "ou=People7,o=bearingpoint,c=com";
        final String ouPeople8 = "ou=People8,o=bearingpoint,c=com";
        final String ouPeople9 = "ou=People9,o=bearingpoint,c=com";

        String strPepple = "";
        if (userName == null || userName.equals("")
                || userName.trim().indexOf(userName.trim().length() - 1) >= 0) {
            strPepple = ouPeople;
        } else {
            String strUserName = userName.trim();
            if (strUserName.substring(strUserName.length() - 1,
                    strUserName.length()).equals("0")) {
                strPepple = ouPeople0;
            } else if (strUserName.substring(strUserName.length() - 1,
                    strUserName.length()).equals("1")) {
                strPepple = ouPeople1;
            } else if (strUserName.substring(strUserName.length() - 1,
                    strUserName.length()).equals("2")) {
                strPepple = ouPeople2;
            } else if (strUserName.substring(strUserName.length() - 1,
                    strUserName.length()).equals("3")) {
                strPepple = ouPeople3;
            } else if (strUserName.substring(strUserName.length() - 1,
                    strUserName.length()).equals("4")) {
                strPepple = ouPeople4;
            } else if (strUserName.substring(strUserName.length() - 1,
                    strUserName.length()).equals("5")) {
                strPepple = ouPeople5;
            } else if (strUserName.substring(strUserName.length() - 1,
                    strUserName.length()).equals("6")) {
                strPepple = ouPeople6;
            } else if (strUserName.substring(strUserName.length() - 1,
                    strUserName.length()).equals("7")) {
                strPepple = ouPeople7;
            } else if (strUserName.substring(strUserName.length() - 1,
                    strUserName.length()).equals("8")) {
                strPepple = ouPeople8;
            } else if (strUserName.substring(strUserName.length() - 1,
                    strUserName.length()).equals("9")) {
                strPepple = ouPeople9;
            } else {
                strPepple = ouPeople;
            }

        }
        return strPepple;
    }

}
